package View;

import java.awt.Color;
import java.awt.Cursor;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.beans.PropertyChangeEvent;

import javax.swing.JButton;
import javax.swing.JPanel;

import zOthers.Log;
import Controller.ControllerGame;
import Model.ModelPanelStartMenu;

public class ViewPanelGame extends AbstractView{

	private static final String TAG = "ViewPanelGame";

	private PanelGame panelGame;
	private ControllerGame controller;

	/*
	 * Copies of those objects also existing in the model. They should always be consistent
	 * with the original copies in the model, or say, they can only be modified when events
	 * of model property change comes
	 */
	private boolean isModelInitialized;
	private BufferedImage imageBackground;
	private Integer selectedMapIndex;
	private Integer screenID;
	private Integer panelGameWidth;
	private Integer panelGameHeight;

	/*
	 * Class PanelStartMenu implements the panelsf
	 */
	public class PanelGame extends JPanel implements MouseMotionListener, MouseListener {

		private static final long serialVersionUID = 1L;

		/*
		 * Inner class constructor
		 */
		public PanelGame() {
			setLayout(null);
			/*
			 * Add mouse motion listener and mouse listener
			 */
			addMouseMotionListener(this);
			addMouseListener(this);
		}

		@Override
		public void paintComponent(Graphics g) {
			Graphics2D g2D = (Graphics2D) g;

			if(imageBackground == null)
				return;

			/*
			 * Draw background image
			 */
			double imageWidth = imageBackground.getWidth();
			double imageHeight = imageBackground.getHeight();
			double panelWidth = panelGame.getWidth();
			double panelHeight = panelGame.getHeight();

			double sx = (panelWidth / imageWidth);
			double sy = (panelHeight / imageHeight);

			g.clearRect(0, 0, 800, 700);
			AffineTransform af = AffineTransform.getScaleInstance(sx, sy);
			g2D.drawImage(imageBackground, af, this);

			if(screenID == ModelPanelStartMenu.SCREEN_ID_LEVEL) {
				/*
				 * Map selector area
				 */
				g2D.setColor(new Color(0.1f, 0.1f, 0.1f, 0.3f));
				g2D.fillRect(0, 100, 800, 400);

				/*
				 * Draw selected map image and title
				 */
				g2D.setColor(Color.DARK_GRAY);
				g2D.setFont(new Font("Arial", Font.PLAIN, 20));
				/*
				 * Draw nearby candidate maps if they exist
				 */			}
		}

		/*
		 * Implement of MouseMotionListener
		 */
		@Override
		public void mouseMoved(MouseEvent evt) {
		}

		@Override
		public void mouseDragged(MouseEvent evt) {
			// Do nothing
		}

		/*
		 * Implement of MouseListener
		 */
		@Override
		public void mouseClicked(MouseEvent evt) {
			// Do nothing
		}

		@Override
		public void mouseEntered(MouseEvent evt) {
			// Do nothing
		}

		@Override
		public void mouseExited(MouseEvent evt) {
			// Do nothing
		}

		@Override
		public void mousePressed(MouseEvent evt) {
			// Do nothing
		}

		@Override
		public void mouseReleased(MouseEvent evt) {
		}
	}

	/*
	 * Constructor
	 */
	public ViewPanelGame() {
		// Do nothing
	}

	/*
	 * Initialize the view
	 * This method is called for only one time when the menu panel is visualized for the first time.
	 * To be more detailed, the method is called right after the view hearing from the model that the
	 * background image has been set.
	 */
	private void viewInitialization() {
		panelGame = new PanelGame();
		panelGame.setBounds(0, 0, panelGameWidth, panelGameHeight);
	}

	/*
	 * Accessors
	 */
	public JPanel getPanel() {
		return panelGame;
	}

	public ControllerGame getController() {
		return controller;
	}

	/*
	 * Mutators
	 */
	public void setController(ControllerGame ctrl) {
		controller = ctrl;
	}

	/*
	 * Clear the entire screen
	 */
	public void clearScreen() {
		panelGame.removeAll();
		System.out.println("RemoveAll() is called");
	}

	/*
	 * Initialize the basic screen
	 */
	private void addComponentsScreenBasic() {
		/*
		 * Clear the panel
		 */
		clearScreen();

		/*
		 * Initialize the buttons
		 */
		JButton testButton = new JButton("Test");

		testButton.setBounds((800 - 150) / 2, 100, 150, 50);

		/*
		 * Add ActionListener to buttons
		 */
		testButton.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent evt) {
				System.out.println();
				controller.testButton();
			}
		});

		/*
		 * Add buttons to the menu
		 */
		panelGame.add(testButton);

		/*
		 * Refresh
		 */
		panelGame.repaint();
	}

	/*
	 * Event handler for modelPropertyChange events coming from the controller
	 */
	@Override
	public void modelPropertyChange(final PropertyChangeEvent evt) {
		String info = "modelPropertyChange() called -- " +
				evt.getPropertyName() + ": " + evt.getOldValue().toString() +
				" -> " + evt.getNewValue().toString();
		Log.info(TAG, info);

		if(evt.getPropertyName().equals("isModelInitialized")) {
			isModelInitialized = Boolean.valueOf(evt.getNewValue().toString());
			if(isModelInitialized == true)
				viewInitialization();
		}
		else if(evt.getPropertyName().equals("screenID")) {
			if(isModelInitialized == false)
				return;
			addComponentsScreenBasic();
		}
		else if(evt.getPropertyName().equals("selectedMapIndex")) {
			selectedMapIndex = (Integer) evt.getNewValue();
			if(screenID == ModelPanelStartMenu.SCREEN_ID_LEVEL)
				//addComponetsScreenLevel();
				panelGame.repaint();
		}
		else if(evt.getPropertyName().equals("imageBackground")) {
			imageBackground = (BufferedImage) evt.getNewValue();
		}
		else if(evt.getPropertyName().equals("panelStartMenuWidth")) {
			panelGameWidth = (Integer) evt.getNewValue();
		}
		else if(evt.getPropertyName().equals("panelStartMenuHeight")) {
			panelGameHeight = (Integer) evt.getNewValue();
		}
		else if(evt.getPropertyName().equals("cursor")) {
			panelGame.setCursor((Cursor) evt.getNewValue());
		}
	}


}
